package com.genius.workflow.ehcache;

import java.sql.SQLException;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import javax.servlet.http.HttpSession;

import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.session.Session;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.genius.adminmanager.menu.entity.MenuJson;
import com.genius.adminmanager.role.entity.RoleJson;
import com.genius.adminmanager.user.entity.UserJson;
import com.genius.workflow.config.DefaultConfiguration;
import com.genius.workflow.util.ConnectionException;
import com.genius.adminmanager.other.entity.SessionJson;
import com.genius.workflow.util.DBClosedException;
import com.genius.workflow.util.DBUtils;

/**
 * 权限验证
 * @author woy
 *
 */
public class PowerUtil {
	
	static{
		CacheUtils.cacheUtils().addCache("admin");
		updatePower();
	}
	public static void updatePower(){
		//把当前的都清空，重新填充
		CacheUtils.cacheUtils().removeAll("admin");
		String sql = "select "+RoleJson.roleId+","+MenuJson.menuId+" from t_role_menu GROUP BY "+RoleJson.roleId+","+MenuJson.menuId;
		try {
			JSONArray arr = DBUtils.selectArr(sql);
			String menuIds = "";
			String oldRoleId = "";
			
			for(int index=0;index<arr.size();index++){
				JSONObject json = arr.getJSONObject(index);
				String roleId = json.getString(RoleJson.roleId);
				if(index==0)//刚开始赋值为一样的
					oldRoleId = roleId;
				menuIds += json.getString(MenuJson.menuId)+",";
				if(!StringUtils.equals(roleId, oldRoleId)){
					if(StringUtils.isNoneBlank(menuIds))
						menuIds = menuIds.substring(0,menuIds.lastIndexOf(","));
					//如果第一次不一样，把上次的结果存档到内存中
					CacheUtils.cacheUtils().addElement("admin", oldRoleId, menuIds);
					
					oldRoleId = roleId;
					menuIds = "";
					//重置的时候把当前的赋值上去
					menuIds += json.getString(MenuJson.menuId)+",";
				}
				//如果最后一个了就统一更新到内存中
				if(index == (arr.size()-1)){
					if(StringUtils.isNoneBlank(menuIds))
						menuIds = menuIds.substring(0,menuIds.lastIndexOf(","));
					CacheUtils.cacheUtils().addElement("admin", roleId, menuIds);
				}
			}
			
			
		} catch (ConnectionException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (DBClosedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	public static boolean hasPower(String [] roleIds,String menuId){
		boolean isHas = false;
		for(String roleId:roleIds){
			String menuIds = (String) CacheUtils.cacheUtils().getElement("admin", roleId);
			if(menuIds ==null){
				continue;
			}
			String [] menuIdsArr = menuIds.split(",");
			for(String id:menuIdsArr){
				if(StringUtils.equals(id, menuId)){
					isHas = true;
					break;
				}
			}
//			for(int index =0;index<roleIdArr.size();index++){
//				String menuIdExist = roleIdArr.getString(index);
//				if(StringUtils.equals(menuIdExist, menuId)){
//					isHas = true;
//					break;
//				}
//			}
		}
		return isHas;
	}
	public static void loadEache(JSONObject userJson,Object session,String currendRoleId){
		try {
			String userId = userJson.getString(UserJson.userId);
			String roleId = null;
			String userId_ = null;
			if(session instanceof HttpSession){
				HttpSession session_ = (HttpSession)session;
				roleId = (String)session_.getAttribute(RoleJson.roleId);
				JSONObject json = ((JSONObject)session_.getAttribute(SessionJson.currentUser));
				userId_ = json==null?null:json.getString(UserJson.userId);
			}else if(session instanceof Session){
				Session session_ = (Session)session;
				roleId = (String)session_.getAttribute(RoleJson.roleId);
				JSONObject json = ((JSONObject)session_.getAttribute(SessionJson.currentUser));
				userId_ = json==null?null:json.getString(UserJson.userId);
			}
			if(roleId != null && userId_!=null && StringUtils.equals(userId_, userId)){
				//说明是第一次进来，session中还没存入当前的角色
				CacheUtils.cacheUtils().removeElement(userId, roleId);
//				return;
			}
			//把上次的session的role角色清理掉
			//存入缓存
			CacheUtils.cacheUtils().addCache(userId);
			String selectMenu = "select "+MenuJson.menuId+" from t_role_menu where roleId=?";
			String [] params = new String[]{currendRoleId};
			JSONArray menuList = DBUtils.selectArr(selectMenu,params);
			JSONArray menuIdArr = new JSONArray();
			for(int i=0;i<menuList.size();i++){
				JSONObject menuJson = menuList.getJSONObject(i);
				menuIdArr.add(menuJson.getString(MenuJson.menuId));
			}
			CacheUtils.cacheUtils().addElement(userId, currendRoleId, menuIdArr);
			
		} catch (ConnectionException e) {
		} catch (DBClosedException e) {
		} catch (SQLException e) {
		}
	}
	public static void doGetAuthorizationInfo(Object session,String currendRoleId){
		
		JSONObject userJson = (JSONObject) SecurityUtils.getSubject().getPrincipal();

		SimpleAuthorizationInfo info=new SimpleAuthorizationInfo();
		String userId = userJson.getString(UserJson.userId);
		if(!CacheUtils.cacheUtils().getCacheManager().cacheExists(userId)){
			loadEache(userJson,session,currendRoleId);
		}
		//检测是否有当前用户的key
		List<Object> objects = CacheUtils.cacheUtils().getKeys(userId);
		if(objects.size()==0){
			loadEache(userJson,session,currendRoleId);
			objects = CacheUtils.cacheUtils().getKeys(userId);
		}
//		if(CacheUtils.cacheUtils().containsKey(userId, "AuthorizationInfo")){
//			return;
//		}
		Set<String> roles=new HashSet<String>();
		for(Object object:objects){
			String roleId = (String)object;
			if(DefaultConfiguration.AuthorizationInfo.equals(roleId)){
				continue;
			}
			roles.add(roleId);
			JSONArray menuIdsArr = (JSONArray)CacheUtils.cacheUtils().getElement(userId, roleId);
			if(menuIdsArr != null){
				for(int index=0;index<menuIdsArr.size();index++){
					String menuId = menuIdsArr.getString(index);
					info.addStringPermission(menuId);
				}
			}else{
				doGetAuthorizationInfo(session,currendRoleId);
			}
		}
		info.setRoles(roles);
		CacheUtils.cacheUtils().addElement(userId, DefaultConfiguration.AuthorizationInfo, info);
	}
}
